#include <gtest/gtest.h>

#include <algorithm>
#include <lru.hpp>
#include <macros.hpp>
#include <optional>
#include <tuple>
#include <vector>

using namespace std;

TEST(LRUTest, Exp1) {
    std::vector<std::tuple<std::string, int, int>> input = {
        {"put", 1, 1},  {"put", 2, 2},  {"get", 1, -1},
        {"put", 3, 3},  {"get", 2, -1}, {"put", 4, 4},
        {"get", 1, -1}, {"get", 3, -1}, {"get", 4, -1}};
    std::vector<std::optional<int>> exret = {std::nullopt,
                                             std::nullopt,
                                             1,
                                             std::nullopt,
                                             -1,
                                             std::nullopt,
                                             -1,
                                             3,
                                             4};
    macro_test("", "", exret, answer, 2, input, false);
}

TEST(LRUTest, Exp2) {
    std::vector<std::tuple<std::string, int, int>> input = {
        {"put", 2, 1}, {"put", 2, 2}, {"get", 2, -1},
        {"put", 1, 1}, {"put", 4, 1}, {"get", 2, -1}};
    std::vector<std::optional<int>> exret = {std::nullopt, std::nullopt, 2,
                                             std::nullopt, std::nullopt, -1};
    macro_test("", "", exret, answer, 2, input, false);
}

TEST(LRUTest, Exp3) {
    std::vector<std::tuple<std::string, int, int>> input = {
        {"put", 2, 1}, {"put", 1, 1},  {"put", 2, 3},
        {"put", 4, 1}, {"get", 1, -1}, {"get", 2, -1}};
    std::vector<std::optional<int>> exret = {
        std::nullopt, std::nullopt, std::nullopt, std::nullopt, -1, 3};
    macro_test("", "", exret, answer, 2, input, false);
}

int main(int argc, char* argv[]) {
    testing::InitGoogleTest(&argc, argv);
    int result = RUN_ALL_TESTS();
    return result;
}